//
//  WKViewTargetActionExtension.swift
//  配送端Swift
//
//  Created by 天下宅 on 16/9/5.
//  Copyright © 2016年 天下宅. All rights reserved.
//

import Foundation
import UIKit

//为一个输入参数为UIView无返回值的函数
public typealias EventHandler = (UIView) -> ()

//保证 字典的键 是可哈希的
public class Event<T: Hashable> {
    
    
    var a:EventHandler?
    
    //定义一个 字典【事件：协议方法】
    private var eventHandlers = [T: Invocable]()
    
    //触发方法
    public func raise(data: T,v:UIView) {
        eventHandlers[data]?.invoke(v: v)
    }
    //为事件设置目标——声明 U 可以是任意类型，handler为任意类型下的EventHandler方法
    func setTarget<U: AnyObject>(target: U, handler: @escaping (U) -> EventHandler, controlEvent: T) {
        eventHandlers[controlEvent] = EventHandlerWrapper(
            target: target, handler: handler)
    }
    //为事件移除目标
    func removeTargetForControlEvent(controlEvent: T) {
        eventHandlers[controlEvent] = nil
    }
}
//定义的协议
private protocol Invocable: class {
    func invoke(v:UIView)
}

private class EventHandlerWrapper<T: AnyObject> : Invocable {
    weak var target: T?
    let handler: (T) -> (UIView) -> ()
    
    init(target: T?, handler: @escaping (T) -> (UIView) -> ()) {
        self.target = target
        self.handler = handler
    }
    
    func invoke(v:UIView) {
        if let t = target {
            handler(t)(v)
        }
    }
}

//定义点击类型，标志位str，只是因为str本身可哈希
public enum WKTapState:String {
    case touchUpInside = "WKTouchUpInside"
}

//定义view事件帮助类
public class UIViewEventHelper: NSObject {
    
    weak var view: UIView?//对应的view
    let event: Event<WKTapState>//事件列表
    
    init(view: UIView) {
        self.view = view
        event = Event<WKTapState>()
        
        super.init()
        //添加手势
        let tap = UITapGestureRecognizer.init(target: self, action: #selector(handleTouchUpInside))
        self.view?.addGestureRecognizer(tap)
    }
    
    //调用方法
    public func handleTouchUpInside() {
        event.raise(data: .touchUpInside,v: self.view!)
    }
    
}

extension UIView {
    
    private struct AssociatedKeys {
        static var EventHelperKey = "EventHelperKey"
    }
    
    private var viewEvent: Event<WKTapState> {
        if let eventHelper = objc_getAssociatedObject(self, &AssociatedKeys.EventHelperKey) as? UIViewEventHelper {
            return eventHelper.event
        }
        
        let eventHelper = UIViewEventHelper(view: self)
        objc_setAssociatedObject(self, &AssociatedKeys.EventHelperKey, eventHelper, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        return eventHelper.event
    }
    
    func addTarget<U: AnyObject>(controlEvent: WKTapState,target: U, handler: @escaping (U) -> EventHandler) {
        viewEvent.setTarget(target: target, handler: handler, controlEvent: controlEvent)
    }
    
}

